package com.xxl.job.executor.helper;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xxl.job.executor.config.WechatPushConfig;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;

@Endpoint(id = "holiday")
@Component
public class HolidayHelper {
    private final Logger log = LoggerFactory.getLogger(HolidayHelper.class);
    @Autowired
    WechatPushConfig config;

//    @PostConstruct
//    public void init() {
//        log.info("组件初始化{}",this.getClass().getName());
//        LocalDate now = LocalDate.now();
//        updateMonthFileAndMap(now);
//        updateYearFileAndMap(now);
//    }

    //========================year==============================

    /**
     * 2024-01-01:{}
     */
    private final TreeMap<LocalDate, Dict> holidayTreeMap = new TreeMap<>();

    public  void updateYearFileAndMap(LocalDate now){
        // 创建当年文件
        createYearFile(now);
        // 生成年信息对应map
        genYearTreeMap(now);
        // 检查下一年数据，并且清空去年及以前数据
        updateNextYear(now);
    }
    private  void updateNextYear(LocalDate now) {
        // 不直接调用createYearFile是因为如果下一年没更新，返回的update是false，没必要保存
        LocalDate next = now.plusYears(1);
        String dayData = getDayData(next.toString(), "1");
        JSONObject entries = JSONUtil.parseObj(dayData);
        Boolean update = entries.getJSONObject("result").getBool("update");
        if(update){
            createYearFile(next);
            genYearTreeMap(next);
        }
    }

    public  void createYearFile(LocalDate now){
        String directory = config.getFileDir();
        String fileName = "holiday_" + now.getYear() + ".json";
        File file = new File(directory + fileName);
        if(!file.exists()){
            String prettyJson = JSONUtil.parse(getDayData(now.toString(),"1")).toStringPretty();// 1-年，2-月
            FileUtil.writeUtf8String(prettyJson, file);
        }
    }

    public  void genYearTreeMap(LocalDate curDate) {
        int year = curDate.getYear();
        String fileName = config.getFileDir()+"holiday_" + curDate.getYear() + ".json";
        JSONObject entries = JSONUtil.readJSONObject(new File(fileName), StandardCharsets.UTF_8);
        JSONArray list = entries.getJSONObject("result").getJSONArray("list");
        List<Dict> dicts = JSONUtil.toList(list, Dict.class);
        for (Dict dict : dicts) {
            String holiday = dict.getStr("holiday");
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d号")
                    .withResolverStyle(ResolverStyle.SMART);
            LocalDate holidayDate = LocalDate.parse(year + "年" + holiday, formatter);
            holidayTreeMap.put(holidayDate, dict);
        }
    }

    public  Map<String,Long> toHoliday(){
        HashMap<String,Long> map = new HashMap<>();
        Iterator<Entry<LocalDate, Dict>> entries = holidayTreeMap.entrySet().iterator();
        while (entries.hasNext()) {
            Entry<LocalDate, Dict> entry = entries.next();
            LocalDate holidayDate = entry.getKey();
            Dict dict = entry.getValue();
            LocalDate now = LocalDate.now();
            long between = ChronoUnit.DAYS.between(now, holidayDate);
            if(between<0){
                entries.remove();
                continue;
            }
            map.put(dict.getStr("name"),between);
        }
        return map;
    }

    //==============================Month====================================
    /**
     * 2024-11-11:{}
     * 2024-11-12:{}
     */
    private final TreeMap<LocalDate, Dict> monthTreeMap = new TreeMap<>();

    public  void updateMonthFileAndMap(LocalDate now){
        createMonthFile(now);
        genMonthTreeMap(now);
    }

    public  void createMonthFile(LocalDate now){
        String filePath = config.getFileDir()+"month_" + now.getMonthValue() + ".json";
        File file = new File(filePath);
        if(!file.exists()){
            String prettyJson = JSONUtil.parse(getDayData(now.toString(),"2")).toStringPretty();// 1-年，2-月
            FileUtil.writeUtf8String(prettyJson, file);
        }
    }

    public  void genMonthTreeMap(LocalDate curDate) {
        monthTreeMap.clear();
        int month = curDate.getMonthValue();
        String fileName =  config.getFileDir()+"month_" + month + ".json";
        JSONObject entries = JSONUtil.readJSONObject(new File(fileName), StandardCharsets.UTF_8);
        JSONArray list = entries.getJSONObject("result").getJSONArray("list");
        List<Dict> dicts = JSONUtil.toList(list, Dict.class);
        for (Dict dict : dicts) {
            String dateStr = dict.getStr("date");
            LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
            monthTreeMap.put(date, dict);
        }
    }

    public  long toWeekendDay(){
        Dict dict = monthTreeMap.get(LocalDate.now());
        Integer weekday = dict.getInt("weekday");
        return Math.max(0,6-weekday);
    }

   // =========================================================
    public  String getDayData(String date,String type){
        String tianapi_data = "";
        try {
            URL url = new URL( "https://apis.tianapi.com/jiejiari/index");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setDoOutput(true);
            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            OutputStream outputStream = conn.getOutputStream();
            String content = "key="+config.getCaiHongPiKey()+"&date="+date+"&type="+type;
            outputStream.write(content.getBytes());
            outputStream.flush();
            outputStream.close();
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader (inputStream,"utf-8");
            BufferedReader bufferedReader = new BufferedReader (inputStreamReader);
            StringBuilder tianapi = new StringBuilder();
            String temp = null;
            while ( null != (temp = bufferedReader.readLine())){
                tianapi.append(temp);
            }
            tianapi_data = tianapi.toString();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(tianapi_data);
        return tianapi_data;
    }

    @ReadOperation
    public Map<String, Object> getMapData() {
        Map<String,Object> map = new HashMap<>();
        map.put("holidayTreeMap",holidayTreeMap);
        map.put("monthTreeMap",monthTreeMap);
        return map;
    }

}
